From 447e70804785b5a0c7bf519307f0037604bdc55e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 9 Feb 2006 12:10:28 +0100 Subject: [PATCH] Fix CPU-migration of VMX domains. Signed-off-by: Yunhong Jiang --- xen/arch/x86/hvm/vmx/vmcs.c | 27 ++++++++++++++++++++++++--- xen/arch/x86/hvm/vmx/vmx.c | 11 +++++++++++ xen/include/asm-x86/hvm/vmx/vmcs.h | 2 ++ xen/include/asm-x86/hvm/vmx/vmx.h | 2 +- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 70bc6111f3..f79be0277e 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -75,6 +75,26 @@ static int load_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr) return 0; } +static void vmx_smp_clear_vmcs(void *info) +{ + struct vcpu *v = (struct vcpu *)info; + + ASSERT(HVM_DOMAIN(v)); + + if (v->arch.hvm_vmx.launch_cpu == smp_processor_id()) + __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); +} + +void vmx_request_clear_vmcs(struct vcpu *v) +{ + ASSERT(HVM_DOMAIN(v)); + + if (v->arch.hvm_vmx.launch_cpu == smp_processor_id()) + __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); + else + smp_call_function(vmx_smp_clear_vmcs, v, 1, 1); +} + #if 0 static int store_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr) { @@ -167,6 +187,7 @@ static void vmx_set_host_env(struct vcpu *v) host_env.tr_base = (unsigned long) &init_tss[cpu]; error |= __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector); error |= __vmwrite(HOST_TR_BASE, host_env.tr_base); + error |= __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom()); } static void vmx_do_launch(struct vcpu *v) @@ -212,7 +233,6 @@ static void vmx_do_launch(struct vcpu *v) shadow_direct_map_init(v); __vmwrite(GUEST_CR3, pagetable_get_paddr(v->domain->arch.phys_table)); __vmwrite(HOST_CR3, pagetable_get_paddr(v->arch.monitor_table)); - __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom()); v->arch.schedule_tail = arch_vmx_do_resume; v->arch.hvm_vmx.launch_cpu = smp_processor_id(); @@ -510,10 +530,11 @@ void arch_vmx_do_resume(struct vcpu *v) } else { - __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); + vmx_request_clear_vmcs(v); load_vmcs(&v->arch.hvm_vmx, virt_to_maddr(v->arch.hvm_vmx.vmcs)); - vmx_do_resume(v); + vmx_migrate_timers(v); vmx_set_host_env(v); + vmx_do_resume(v); v->arch.hvm_vmx.launch_cpu = smp_processor_id(); reset_stack_and_jump(vmx_asm_do_relaunch); } diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 87324155eb..fd0edf1272 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -91,6 +91,7 @@ void vmx_relinquish_resources(struct vcpu *v) (void *)d->arch.hvm_domain.shared_page_va); } + vmx_request_clear_vmcs(v); destroy_vmcs(&v->arch.hvm_vmx); free_monitor_pagetable(v); vpit = &v->domain->arch.hvm_domain.vpit; @@ -338,6 +339,16 @@ int vmx_relinquish_guest_resources(struct vcpu *v) return 1; } +void vmx_migrate_timers(struct vcpu *v) +{ + struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit); + + migrate_timer(&vpit->pit_timer, v->processor); + migrate_timer(&v->arch.hvm_vmx.hlt_timer, v->processor); + if ( hvm_apic_support(v->domain) && VLAPIC(v)) + migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor); +} + void vmx_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs) { #if defined (__x86_64__) diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index 84b407367b..54820bcb2b 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -95,6 +95,8 @@ int modify_vmcs(struct arch_vmx_struct *arch_vmx, struct cpu_user_regs *regs); void destroy_vmcs(struct arch_vmx_struct *arch_vmx); +extern void vmx_request_clear_vmcs(struct vcpu *v); + #define VMCS_USE_HOST_ENV 1 #define VMCS_USE_SEPARATE_ENV 0 diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index 52b0551c12..6d551edf8e 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -31,7 +31,7 @@ extern void vmx_asm_do_resume(void); extern void vmx_asm_do_launch(void); extern void vmx_intr_assist(void); extern void vmx_set_tsc_shift(struct vcpu *, struct hvm_virpit *); - +extern void vmx_migrate_timers(struct vcpu *v); extern void arch_vmx_do_launch(struct vcpu *); extern void arch_vmx_do_resume(struct vcpu *); -- 2.30.2